package com.tich.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tich.api.client.UserClient;
import com.tich.api.domain.vo.UserSimpleVO;
import com.tich.blog.domain.dto.BlogCommentDTO;
import com.tich.blog.domain.dto.BlogSonCommentDTO;
import com.tich.blog.domain.dto.CommentPublishDTO;
import com.tich.blog.domain.entity.BlogComments;
import com.tich.blog.domain.vo.BlogCommentVO;
import com.tich.blog.domain.vo.CommentSimpleVO;
import com.tich.blog.mapper.BlogCommentsMapper;
import com.tich.blog.service.IBlogCommentsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tich.constant.SQLConstant;
import com.tich.context.UserContext;
import com.tich.utils.IdGeneratorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 博客评论表 服务实现类
 * </p>
 *
 * @author 王志宇
 * @since 2025-05-14
 */
@Slf4j
@Service
public class BlogCommentsServiceImpl extends ServiceImpl<BlogCommentsMapper, BlogComments> implements IBlogCommentsService {

    @Autowired
    private UserClient userClient;

    /**
     * d根据帖子id删除帖子相关的评论
     *
     * @param blogId
     */
    @Override
    public void deleteCommentByBlogId(Long blogId) {
        //检验
        if (blogId == null) {
            return;
        }
        //构建wrapper
        LambdaQueryWrapper<BlogComments> deleteWrapper = Wrappers.lambdaQuery(BlogComments.class)
                .eq(BlogComments::getBlogId, blogId);

        // 执行删除
        boolean success = remove(deleteWrapper);

        //根据删除结果抛异常或记录日志
        if (!success) {
            log.warn("根据 blogId= {} 删除评论失败，可能无匹配记录", blogId);
        }
    }

    /**
     * 发表评论
     *
     * @param commentPublishDTO
     */
    @Override
    public void saveBlogComment(CommentPublishDTO commentPublishDTO) {
        Long Id = IdGeneratorUtil.getInstance().nextId();
        BlogComments blogComments = BeanUtil.toBean(commentPublishDTO, BlogComments.class)
                .setId(Id)
                .setUserId(UserContext.getCurrentId())
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());
        save(blogComments);
    }

    /**
     * 删除评论
     *
     * @param commentId
     */
    @Override
    public void deleteCommentById(Long commentId) {
        //根据评论id查询
        BlogComments blogComment = getById(commentId);
        //不存在
        if (blogComment == null) {
            return;
        }
        //是否是父评论
        if (blogComment.getParentId() != null) {
            removeById(commentId);
            return;
        }

        LambdaQueryWrapper<BlogComments> deleteWrapper = Wrappers.lambdaQuery(BlogComments.class)
                .eq(BlogComments::getParentId, commentId);


        remove(deleteWrapper);
        removeById(commentId);

    }

    /**
     * 获取帖子评论
     *
     * @param blogCommentDTO
     */
    @Override
    public CommentSimpleVO queryComments(BlogCommentDTO blogCommentDTO) { // 增加DTO参数
        // 1. 构建查询条件（按时间倒序 + cursor 过滤）
        LambdaQueryWrapper<BlogComments> queryWrapper = Wrappers.lambdaQuery(BlogComments.class)
                .eq(BlogComments::getBlogId, blogCommentDTO.getBlogId())
                .isNull(BlogComments::getParentId)
                .orderByDesc(BlogComments::getCreateTime)
                .last(SQLConstant.LIMIT + "10");

        // 添加cursor条件（如果存在）
        if (blogCommentDTO.getCursor() != null) {
            queryWrapper.lt(BlogComments::getCreateTime, blogCommentDTO.getCursor());
        }

        // 2. 执行查询
        List<BlogComments> parents = getBaseMapper().selectList(queryWrapper);


        // 提取评论中的用户ID（去重）
        List<Long> userIds = parents.stream()
                .map(BlogComments::getUserId)
                .distinct()
                .collect(Collectors.toList());

        // 批量查询用户信息（改用UserSimpleVO）
        List<UserSimpleVO> users = userIds.isEmpty() ?
                Collections.emptyList() :
                userClient.getByIds(userIds);
        Map<Long, UserSimpleVO> userMap = users.stream()
                .collect(Collectors.toMap(UserSimpleVO::getId, vo -> vo));

        // 转换VO时填充用户信息
        List<BlogCommentVO> voList = convertToVOList(parents, userMap);

        // 3. 计算下一次的cursor（取最后一条时间）
        LocalDateTime nextCursor = null;
        if (!parents.isEmpty()) {
            nextCursor = parents.get(parents.size() - 1).getCreateTime();
        }

        // 4. 转换为VO
        return CommentSimpleVO.builder()
                .cursor(nextCursor)
                .datas(voList)
                .build();
    }

    /**
     * 获取帖子评论的子评论
     *
     * @param blogSonCommentDTO
     */
    @Override
    public CommentSimpleVO getBlogSonComments(BlogSonCommentDTO blogSonCommentDTO) {
        // 1. 构建查询条件（按时间倒序 + cursor 过滤）
        LambdaQueryWrapper<BlogComments> queryWrapper = Wrappers.lambdaQuery(BlogComments.class)
                .eq(BlogComments::getParentId, blogSonCommentDTO.getParentID())
                .orderByDesc(BlogComments::getCreateTime)
                .last(SQLConstant.LIMIT + "10");

        // 添加cursor条件（如果存在）
        if (blogSonCommentDTO.getCursor() != null) {
            queryWrapper.lt(BlogComments::getCreateTime, blogSonCommentDTO.getCursor());
        }

        // 2. 执行查询
        List<BlogComments> sons = getBaseMapper().selectList(queryWrapper);

        // 3. 提取评论中的用户ID（去重）
        List<Long> userIds = sons.stream()
                .map(BlogComments::getUserId)
                .distinct()
                .collect(Collectors.toList());

        // 批量查询用户信息
        List<UserSimpleVO> users = userIds.isEmpty() ?
                Collections.emptyList() :
                userClient.getByIds(userIds);
        Map<Long, UserSimpleVO> userMap = users.stream()
                .collect(Collectors.toMap(UserSimpleVO::getId, vo -> vo));

        // 转换VO时填充用户信息
        List<BlogCommentVO> voList = convertToVOList(sons, userMap);

        // 5. 计算下一次的cursor（取最后一条时间）
        LocalDateTime nextCursor = null;
        if (!sons.isEmpty()) {
            nextCursor = sons.get(sons.size() - 1).getCreateTime();
        }

        // 6. 转换为VO（传入用户信息Map）
        return CommentSimpleVO.builder()
                .cursor(nextCursor)
                .datas(voList)
                .build();
    }


    /**
     * 将blogComment转换为BlogCommentVO
     *
     * @param comments
     * @return
     */
    // 转换方法，传入用户信息Map
    private List<BlogCommentVO> convertToVOList(
            List<BlogComments> comments,
            Map<Long, UserSimpleVO> userMap
    ) {
        return comments.stream().map(comment -> {
            UserSimpleVO user = userMap.get(comment.getUserId());
            return BlogCommentVO.builder()
                    .id(comment.getId())
                    .userId(comment.getUserId())
                    .content(comment.getContent())
                    .username(user != null ? user.getUsername() : "未知用户")
                    .image(user != null ? user.getImage() : null)
                    .createTime(comment.getCreateTime())
                    .liked(comment.getLiked())
                    .build();
        }).collect(Collectors.toList());
    }

}

